﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using CRL.Core;
using System.Reflection;
using CRL.Data;
using System.Collections.Concurrent;

namespace CRL.Data.LambdaQuery
{
    public partial class ExpressionVisitor
    {
        List<string> existsTempParameName;
        CRLExpression.CRLExpression BinaryExpressionHandler(Expression left, Expression right, ExpressionType expType)
        {
            var isBinary = binaryTypes.Contains(expType);
            //string key = "";
            string typeStr = ExpressionTypeCast(expType);
            string __typeStr2 = typeStr;
            string outLeft, outRight;
            bool isNullValue = false;

            var leftPar = RouteExpressionHandler(left);
            var rightPar = RouteExpressionHandler(right);
            #region 修正bool值一元运算
            //b => b.IsTop && b.Id < 10
            if (expType == ExpressionType.AndAlso || expType == ExpressionType.OrElse)
            {
                if (leftPar.Type == CRLExpression.CRLExpressionType.Name)
                {
                    left = left.Equal(Expression.Constant(true));
                    leftPar = RouteExpressionHandler(left);
                }
                else if (rightPar.Type == CRLExpression.CRLExpressionType.Name)
                {
                    right = right.Equal(Expression.Constant(true));
                    rightPar = RouteExpressionHandler(right);
                }
            }
            #endregion
            outLeft = DealCRLExpression(left, leftPar, typeStr, out isNullValue, true);
            outRight = DealCRLExpression(right, rightPar, typeStr, out isNullValue, true);
            #region 固定名称的参数
            if (isBinary && SettingConfig.FieldParameName)
            {
                if ((int)(leftPar.Type | rightPar.Type) == 12)
                {
                    CRLExpression.CRLExpression tempName;
                    CRLExpression.CRLExpression tempValue;
                    if (leftPar.Type == CRLExpression.CRLExpressionType.Name)
                    {
                        tempName = leftPar;
                        tempValue = rightPar;
                    }
                    else
                    {
                        tempName = rightPar;
                        tempValue = leftPar;
                        outLeft = outRight;
                    }
                    existsTempParameName = existsTempParameName ?? new List<string>();
                    var pre = lambdaQueryBase.GetPrefix(tempName.MemberType,tempName.typeParameterName);
                    pre = pre.Replace(".", $"_");
                    var pName = __DBAdapter.GetParamName(pre, tempName.Data_);
                    if (existsTempParameName.Contains(pName))
                    {
                        pName = pName.Replace("_", "_" + existsTempParameName.Count + "_");
                    }
                    AddParame(pName, tempValue.Data);
                    existsTempParameName.Add(pName);
                    outRight = pName;
                }
            }
            #endregion
            if (isNullValue)//left为null则语法错误
            {
                __typeStr2 = "";
            }
            string sb = string.Format("{0}{1}{2}", outLeft, __typeStr2, outRight);
            //if (isBinary || expType == ExpressionType.OrElse)
            //{
            //    sb = string.Format("({0}{1}{2})", outLeft, __typeStr2, outRight);
            //}
            //else
            //{
            //    sb = string.Format("{0}{1}{2}", outLeft, __typeStr2, outRight);
            //}
            var e = new CRLExpression.CRLExpression() { ExpType = expType, Left = leftPar, Right = rightPar, Type = isBinary ? CRLExpression.CRLExpressionType.Binary : CRLExpression.CRLExpressionType.Tree };
            e.SqlOut = sb;
            e.Data = e.SqlOut;

            return e;
        }
    }
}
